package com.lu.sb210207.components;

import com.lu.sb210207.entity.ScheduleTrigger;
import com.lu.sb210207.entity.ScheduleTriggerParam;
import com.lu.sb210207.mapper.ScheduleTriggerMapper;
import com.lu.sb210207.mapper.ScheduleTriggerParamMapper;
import org.quartz.*;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.List;

@Service
public class QuartzTest {

    //获取调度器实例
    @Autowired
    private Scheduler scheduler;

    @Autowired
    private ScheduleTriggerMapper scheduleTriggerMapper;

    @Autowired
    private ScheduleTriggerParamMapper scheduleTriggerParamMapper;

    //    @Scheduled(cron = "*/10 * * * * ?")
    public void reflushScheduler() {
        try {
            //1.循环获取数据库里面的所有定时任务信息
            List<ScheduleTrigger> list = scheduleTriggerMapper.queryScheduleTrigger();
            //2.循环遍历
            for (ScheduleTrigger scheduleTtrigger : list) {
                //获取cron表达式
                String cron = scheduleTtrigger.getCron();
                //获取Jobname,job任务类的全路径名
                String jobname = scheduleTtrigger.getJobName();
                //获取JobGroup
                String jobGroup = scheduleTtrigger.getJobGroup();
                //获取Status运行状态
                String status = scheduleTtrigger.getStatus();
                //3.根据Jobname和JobGroup生成TriggerKey
                TriggerKey triggerKey = TriggerKey.triggerKey(jobname, jobGroup);
                //4根据TriggerKey获取Scheduler调度器中的触发器，并判断是否为null，不为null即存在
                CronTrigger trigger = (CronTrigger) scheduler.getTrigger(triggerKey);
                //5判断是否为null
                if (null == trigger) {
                    //6.判断当前kob任务是否可用
                    if (status.equals("0")) {
                        continue;
                    }
                    //7.创建JobDetail
                    JobDetail jobDetail = JobBuilder.newJob((Class<? extends Job>) Class.forName(jobname))
                            .withIdentity(jobname, jobGroup)
                            .build();
                    //8.传递参数到job任中
                    JobDataMap jobDataMap = jobDetail.getJobDataMap();
                    //获取调度器任务id
                    Integer scheduleid = scheduleTtrigger.getId();
                    List<ScheduleTriggerParam> params = scheduleTriggerParamMapper.queryScheduleParams(scheduleid);
                    for (ScheduleTriggerParam param : params) {
                        jobDataMap.put(param.getName(), param.getValue());
                    }
                    //9.创建cron表达式调度器
                    CronScheduleBuilder cronScheduleBuilder = CronScheduleBuilder.cronSchedule(cron);
                    //10 创建cron表达式触发器
                    trigger = TriggerBuilder.newTrigger()
                            .withIdentity(jobname, jobGroup)
                            .withSchedule(cronScheduleBuilder)
                            .build();
                    //11.将jobDetail和Trigger注入到调度器中
                    scheduler.scheduleJob(jobDetail, trigger);
                } else {
                    System.out.println("Quartz调度器实例已经存在");
                    if (status.equals("0")) {
                        //删除调度任务
                        JobKey jobKey = JobKey.jobKey(jobname, jobGroup);
                        scheduler.deleteJob(jobKey);
                        continue;
                    }

                    //获取调度器中的表达式
                    String cronExpression = trigger.getCronExpression();
                    //将调度器中的cron与数据库中的job任务进行比对
                    if (!cron.equals(cronExpression)) {
                        //重构表达式调度器
                        CronScheduleBuilder newCronSchedule = CronScheduleBuilder.cronSchedule(cron);
                        //重构CronTrigger
                        trigger = TriggerBuilder.newTrigger()
                                .withIdentity(triggerKey)
                                .withSchedule(newCronSchedule)
                                .build();
                        //刷新调度器实例
                        scheduler.rescheduleJob(triggerKey, trigger);

                    }
                }
            }
        } catch (Exception e) {
            e.printStackTrace();
        }


    }

}
